using System.Linq;
using System.Xml.Linq;

#tool "nuget:?package=xunit.runner.console"
#tool "nuget:?package=GitVersion.CommandLine&version=3.6.4"
#tool "nuget:?package=OctopusTools"
#tool "nuget:?package=MSBuild.SonarQube.Runner.Tool"
#addin "nuget:?package=Cake.Sonar"
#addin "Cake.Npm"

var target        = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
var skipSonar     = HasArgument("skipSonar");

var solutionPath   = "All.sln";
var buildDirs      = "./**/bin/" + configuration;
var octopackedDirs = "./**/octopacked";
var nugetOutputDir = "./artifacts";
var uiFolder       = "./Sustainalytics.Synchronization.Service/app/";

var isLocalBuild        = BuildSystem.IsLocalBuild;
var gitVersion          = GitVersion();
var releaseNumber       = gitVersion.NuGetVersion;
var branch              = gitVersion.BranchName.ToLowerInvariant();
var shouldCreateRelease = branch == "master" || branch == "develop" || branch.StartsWith("release") || branch.StartsWith("hotfix");
var xUnitResultFilename = "XUnitResults";

Information("");
Information("Release Number = " + releaseNumber);
Information("Branch Name = " + branch);
Information("ShouldCreateRelease = " + shouldCreateRelease);
Information("IsLocalBuild = " + isLocalBuild);

var octopusDeploy = new {
  ProjectName = "GA.Services",
  Server      = "http://10.120.120.11:8082",
  ApiKey      = "API-MBFQMNHSNQE2OQHPSBIQH3MKEY",
};

var sonar = new {
  Url      = "http://10.120.120.11:9000",
  Login    = "admin",
  Password = "Calling!3",
  Key      = "GA.Services",
};

if (BuildSystem.IsRunningOnTeamCity) {
  TeamCity.SetBuildNumber(releaseNumber);
}

Task("Clean")
  .Does(() => {
    EnsureDirectoryExists(nugetOutputDir);
    CleanDirectories(buildDirs);
    CleanDirectories(octopackedDirs);
    CleanDirectories(nugetOutputDir);
  });
  	
Task("NpmInstall")
  .Does(() => NpmInstall(new NpmInstallSettings { WorkingDirectory = uiFolder }));

Task("NuGetRestore")
  .Does(() => NuGetRestore(solutionPath));

Task("Build")
  .IsDependentOn("Clean")
  .IsDependentOn("NpmInstall")
  .IsDependentOn("NuGetRestore")
  .Does(() => {
    var msBuildSettings = new MSBuildSettings()
      .SetConfiguration(configuration)
      .SetNodeReuse(false)
      .SetPlatformTarget(PlatformTarget.MSIL);

    if (!isLocalBuild) {
      msBuildSettings = msBuildSettings
        .WithProperty("RunOctoPack", "true")
        .WithProperty("OctoPackEnforceAddingFiles", "true")
        .WithProperty("OctoPackPackageVersion", releaseNumber)
        .WithProperty("OctoPackNuGetProperties", "Configuration=" + configuration);
    }

    MSBuild(solutionPath, msBuildSettings);

    if (!isLocalBuild) {
      CopyFiles(GetFiles(octopackedDirs + "/*.nupkg"), nugetOutputDir);
    }
  });

Task("RunUnitTests")
  .Does(() => {
    var xunit2Settings = new XUnit2Settings {
      Parallelism     = ParallelismOption.All,
      NoAppDomain     = false,
      XmlReport       = true,
      ReportName      = xUnitResultFilename,
      OutputDirectory = ".",
    };
    xunit2Settings.IncludeTrait("Category", "Unit");
    XUnit2(buildDirs + "/*.Tests.dll", xunit2Settings);
  });

Task("CleanXUnitResults")
	.Does(() => {
		var doc = XElement.Load(xUnitResultFilename + ".xml");
		doc.Descendants().Where(e => e.Attribute("total") == null).Remove();
		doc.Save(xUnitResultFilename + ".xml");
	});

Task("NuGetPush")
  .WithCriteria(!isLocalBuild && shouldCreateRelease)
  .Does(() => {
    var packages = GetFiles(nugetOutputDir + "/*.nupkg").ToList();
    var nuGetPushSettings = new NuGetPushSettings {
      Source = octopusDeploy.Server + "/nuget/packages",
      ApiKey = octopusDeploy.ApiKey,
    };
    NuGetPush(packages, nuGetPushSettings);
  });

Task("OctoCreateRelease")
  .WithCriteria(!isLocalBuild && shouldCreateRelease)
  .Does(() => {
    var createReleaseSettings = new CreateReleaseSettings {
      Server         = octopusDeploy.Server,
      ApiKey         = octopusDeploy.ApiKey,
      PackagesFolder = nugetOutputDir,
      ReleaseNumber  = releaseNumber,
    };
	
	OctoCreateRelease("GA.Cuda", createReleaseSettings);
	OctoCreateRelease("GA.Reports", createReleaseSettings);
    OctoCreateRelease("GA.Services", createReleaseSettings);
  });

Task("SonarBegin")
  .WithCriteria(!isLocalBuild && !skipSonar)
  .Does(() => {
     SonarBegin(new SonarBeginSettings {
        Url      = sonar.Url,
        Login    = sonar.Login,
        Password = sonar.Password,
        Key      = sonar.Key,
        Version  = releaseNumber,
        XUnitReportsPath = xUnitResultFilename + ".xml",
     });
  });

Task("SonarEnd")
  .WithCriteria(!isLocalBuild && !skipSonar)
  .Does(() => {
     SonarEnd(new SonarEndSettings{
        Login    = sonar.Login,
        Password = sonar.Password,
     });
  });

Task("Default")
  .IsDependentOn("SonarBegin")
  .IsDependentOn("Build")
  .IsDependentOn("RunUnitTests")
  .IsDependentOn("CleanXUnitResults")
  .IsDependentOn("SonarEnd")
  .IsDependentOn("NuGetPush")
  .IsDependentOn("OctoCreateRelease");

RunTarget(target);
